﻿namespace MicroCloud.Utils
{
    /// <summary>
    /// 服务集合接口辅助扩展方法类
    /// </summary>
    public static class ServiceCollectionExtensions
    {
        /// <summary>
        /// 判断指定服务类型是否存在
        /// </summary>
        /// <param name="services">服务集合</param>
        /// <param name="serviceType">指定服务的类型</param>
        /// <returns></returns>
        public static bool Any(this IServiceCollection services, Type serviceType)
        {
            return services.Any(m => m.ServiceType == serviceType);
        }

        /// <summary>
        /// 如果指定服务不存在，添加指定服务。
        /// </summary>
        /// <param name="services"></param>
        /// <param name="toAdDescriptor"></param>
        /// <returns></returns>
        public static ServiceDescriptor GetOrAdd(this IServiceCollection services, ServiceDescriptor toAdDescriptor)
        {
            ServiceDescriptor descriptor = services.FirstOrDefault(m => m.ServiceType == toAdDescriptor.ServiceType);
            if (descriptor != null)
            {
                return descriptor;
            }

            services.Add(toAdDescriptor);
            return toAdDescriptor;
        }

        /// <summary>
        /// 替换服务
        /// </summary>
        /// <typeparam name="TService"></typeparam>
        /// <typeparam name="TImplement"></typeparam>
        /// <param name="services"></param>
        /// <param name="lifetime"></param>
        /// <returns></returns>
        public static IServiceCollection Replace<TService, TImplement>(this IServiceCollection services, ServiceLifetime lifetime)
        {
            ServiceDescriptor descriptor = new(typeof(TService), typeof(TImplement), lifetime);
            services.Replace(descriptor);
            return services;
        }

        /// <summary>
        /// 获取单例注册服务对象
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="services"></param>
        /// <returns></returns>
        public static T GetSingletonOrDefault<T>(this IServiceCollection services)
        {
            ServiceDescriptor descriptor = services.FirstOrDefault(d => d.ServiceType == typeof(T) && d.Lifetime == ServiceLifetime.Singleton);

            if (descriptor?.ImplementationInstance != null)
            {
                return (T)descriptor.ImplementationInstance;
            }

            if (descriptor?.ImplementationFactory != null)
            {
                return (T)descriptor.ImplementationFactory.Invoke(null);
            }

            return default;
        }

        /// <summary>
        /// 获取单例注册服务对象
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="services"></param>
        /// <returns></returns>
        public static T GetSingleton<T>(this IServiceCollection services)
        {
            var instance = services.GetSingletonOrDefault<T>();
            if (instance == null)
            {
                throw new InvalidOperationException(I18N.T("无法找到已注册的单例服务 {0}", typeof(T).AssemblyQualifiedName));
            }
            return instance;
        }

    }
}
